<?php
/**
 * 事件缓存命令：替代 php artisan event:cache
 */

namespace Jammiest\SwigeCore\Console\Commands\Cache;

use Jammiest\SwigeCore\Console\Commands\Command;
use Jammiest\SwigeCore\Tools\Path;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(name: 'event:cache')]
class EventCommand extends Command
{
    protected function configure()
    {
        $this->setDescription('缓存事件监听器中');
    }

    protected function execute(InputInterface $input, OutputInterface $output):int
    {
        $io = new SymfonyStyle($input, $output);
        $io->title('缓存事件监听器');
        
        try {
            $cacheFile = Path::getBasePath('storage/framework/cache/events.php');
            // $cacheFile = storage_path('framework/cache/events.php');
            $cacheDir = dirname($cacheFile);
            
            if (!is_dir($cacheDir)) {
                mkdir($cacheDir, 0755, true);
            }
            
            // 扫描事件监听器
            $events = $this->scanEventListeners();
            
            // 写入缓存文件
            $cacheContent = '<?php return ' . var_export($events, true) . ';';
            file_put_contents($cacheFile, $cacheContent);
            
            $io->success('事件缓存已生成: ' . $cacheFile);
            return Command::SUCCESS;
            
        } catch (\Exception $e) {
            $io->error('事件缓存失败: ' . $e->getMessage());
            return Command::FAILURE;
        }
    }

    private function scanEventListeners()
    {
        $events = [];
        $listenerFiles = glob(Path::getBasePath('app/Listeners/*.php'));
        // $listenerFiles = glob(app_path('Listeners/*.php'));
        
        foreach ($listenerFiles as $file) {
            $className = 'App\\Listeners\\' . basename($file, '.php');
            if (class_exists($className)) {
                $events[] = [
                    'listener' => $className,
                    'event' => $this->getEventForListener($className)
                ];
            }
        }
        
        return $events;
    }

    private function getEventForListener($listenerClass)
    {
        // 简单的反射获取事件类型
        try {
            $reflection = new \ReflectionClass($listenerClass);
            $method = $reflection->getMethod('handle');
            $params = $method->getParameters();
            
            return $params[0]->getType()->getName();
        } catch (\Exception $e) {
            return 'unknown';
        }
    }
}